package com.supreme.studyserver.service;

import com.supreme.studyserver.entity.Test;
import com.supreme.studyserver.thread.ImplThread;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

@Service
public class JucQueueService {

    private ArrayBlockingQueue<Test> arrayBlockingQueue;
    private LinkedBlockingQueue<Thread> linkedBlockingQueue;

    @PostConstruct
    public void initArrayBlockingQueue() {
        System.out.println("initArrayBlockingQueue");
        arrayBlockingQueue = new ArrayBlockingQueue<>(4);
        linkedBlockingQueue = new LinkedBlockingQueue<>(1);
    }

    public void testArrayQueueTest(int count) {
        ArrayBlockingQueue<Integer> testQueue = new ArrayBlockingQueue<>(4);
        for (int i = 0; i < count; i++) {
            final boolean result = testQueue.offer(i + 1);
            System.out.println("result: " + result);
        }
    }

    public void testLinkedQueueTest(int count) {
        LinkedBlockingQueue<Integer> testQueue = new LinkedBlockingQueue<>(4);
        for (int i = 0; i < count; i++) {
            final boolean result = testQueue.offer(i + 1);
            System.out.println("result: " + result);
        }
    }

    public void putTestQueue(Test test) {
        try {
            arrayBlockingQueue.put(test);
        } catch (InterruptedException e) {
            System.out.println(e.getMessage());
        }
    }

    public Test takeTestQueue() {
        Test result = null;
        try {
            result = arrayBlockingQueue.take();
        } catch (InterruptedException e) {
            System.out.println(e.getMessage());
        }

        return result;
    }

    public void putRunnableQueue() {
        try {
            final String threadName = Thread.currentThread().getName();
            final Thread thread = new Thread(new ImplThread(5, threadName));
            linkedBlockingQueue.put(thread);
        } catch (InterruptedException e) {
            System.out.println(e.getMessage());
        }
    }

    public void takeRunnableQueue() {
        try {
            final Thread thread = linkedBlockingQueue.take();
            thread.start();
        } catch (InterruptedException e) {
            System.out.println(e.getMessage());
        }
    }

    @Async(value = "supremeTaskExecutor")
    public void listenRunnableQueue() {
        while (true) {
            try {
                System.out.println("listenRunnableQueue: " + Thread.currentThread().getName());
                final Thread thread = linkedBlockingQueue.take();
                thread.start();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
